package other;

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

public class MyCalcuStackTest {
    public static void main(String[] args) {
        String expression = "2+(7*2)*2-5+1-((5+4))-3";
        int result = calculate1(expression);
        System.out.println(result);
    }

    private static int calculate(String expression) {
        char[] ex = expression.toCharArray();
        String numStr="";
        Map<Character,Integer> opPriorityMap = new HashMap<>();
        opPriorityMap.put('+',1);
        opPriorityMap.put('*',2);
        opPriorityMap.put('/',2);

        Stack<Integer> numStack = new Stack<>();
        Stack<Character> opStack = new Stack<>();

        char c;
        if(ex.length==0){
            return 0;
        }

        if(ex[0]<'0'&&ex[0]>'9'){
            if(ex[0]!='-'){
                return 0;
            }
        }

        c=ex[ex.length-1];
        if(c=='+'||c=='-'||c=='*'||c=='/'){
            return 0;
        }

        for(int i=0;i<ex.length;i++){
            c=ex[i];
            if(c>'0'&&c<'9'){
                numStr+=c;
            }else if(c=='+'||c=='-'||c=='*'||c=='/'){
                numStack.push(Integer.valueOf(numStr));
                numStr="";
                if(c=='-'){
                    numStr+=c;
                    c='+';
                }
                while(!opStack.empty()){
                    if(opPriorityMap.get(opStack.peek())<=opPriorityMap.get(c)){
                        break;
                    }
                    int result = step(numStack,opStack);
                    numStack.push(result);
                }
                opStack.push(c);
            } else {
                return 0;
            }

        }
        System.out.println(opStack);
        numStack.push(Integer.valueOf(numStr));
        System.out.println(numStack);
        while(!opStack.empty()){
            int result = step(numStack,opStack);
            numStack.push(result);
            System.out.println(opStack);
            System.out.println(numStack);
        }

        return numStack.pop();
    }

    private static int step(Stack<Integer> numStack, Stack<Character> opStack) {
        int num2 = numStack.pop();
        int num1 = numStack.pop();
        char op = opStack.pop();
        if(op=='+'){
            return num1+num2;
        }else if(op=='-'){
            return num1-num2;
        }else if(op=='*'){
            return num1*num2;
        }else if(op=='/'){
            return num1/num2;
        }else {
            return 0;
        }
    }

    //实现括号功能
    private static int calculate1(String expression) {
        char[] ex = expression.toCharArray();
        Node result = calc(ex,0);
        if(result==null){
            return 0;
        }
        return result.getResult();
    }

    private static Node calc(char[] ex, int start) {
        /*"2+(7*2)*2-5+1-5+4-3"*/
        String numStr="";
        Map<Character,Integer> opPriorityMap = new HashMap<>();
        opPriorityMap.put('+',1);
        opPriorityMap.put('*',2);
        opPriorityMap.put('/',2);

        Stack<Integer> numStack = new Stack<>();
        Stack<Character> opStack = new Stack<>();

        char c;
        if(ex.length==0){
            return null;
        }

        if(ex[0]<'0'&&ex[0]>'9'){
            if(ex[0]!='-'){
                return null;
            }
        }

        c=ex[ex.length-1];
        if(c=='+'||c=='-'||c=='*'||c=='/'){
            return null;
        }

        int i=0;
        for(i=start;i<ex.length;i++){
            c=ex[i];
            if(c>'0'&&c<'9'){
                numStr+=c;
            }else if(c=='+'||c=='-'||c=='*'||c=='/'){
                System.out.println(numStack);
                System.out.println(opStack);
                numStack.push(Integer.valueOf(numStr));
                numStr="";
                if(c=='-'){
                    numStr+=c;
                    c='+';
                }
                while(!opStack.empty()){
                    if(opPriorityMap.get(opStack.peek())<=opPriorityMap.get(c)){
                        break;
                    }
                    int result = step(numStack,opStack);
                    numStack.push(result);
                }
                opStack.push(c);
            }else if(c=='('){
                Node result = calc(ex,i+1);
                if(result==null){
                    System.out.println("语法错误");
                    return null;
                }
                //可能出现8(48)错误输入
                numStr += result.getResult();
                //numStack.push(result);
                //int j=0;
/*                for(j=i+1;j<ex.length;j++){
                    if(ex[j]==')'){
                        i=j;
                        break;
                    }
                }*/

/*                if(j==ex.length){
                    System.out.println("括号不成对");
                    return 0;
                }*/
                //opStack.push(c);
                i=result.getEnd();
            }else if(c==')'){
                break;
            }else {
                return null;
            }

        }

        numStack.push(Integer.valueOf(numStr));
        System.out.println(numStack);
        System.out.println(opStack);
        while(!opStack.empty()){
            int result = step(numStack,opStack);
            numStack.push(result);
        }
        Node node = new Node(numStack.pop(),i);
        return node;
    }

}

class Node{
    int result;
    int end;

    public Node() {
    }

    public Node(int result, int end) {
        this.result = result;
        this.end = end;
    }

    public int getResult() {
        return result;
    }

    public void setResult(int result) {
        this.result = result;
    }

    public int getEnd() {
        return end;
    }

    public void setEnd(int end) {
        this.end = end;
    }
}